1 import pygame
2 import time
3 import random
4
5 pygame.init()
6
7 display_width =
800
8 display_height =
600
9
10 gameDisplay = pygame.display.set_mode((display_width, display_height))
11
12
13 pygame.display.set_caption(
'Tank Destroyer Game')
14
15
16 wheat=(
245,222,179)
17
18 white = (
255, 255, 255)
19 black = (
0, 0, 0)
20 blue = (
0,0,255)
21
22 red = (
200, 0, 0)
23 light_red = (
255, 0, 0)
24 pink=(
255,192,203)
25 yellow = (
200, 200, 0)
26 light_yellow = (
255, 255, 0)
27
28 green = (
34, 177, 76)
29 light_green = (
0, 255, 0)
30
31 clock = pygame.time.Clock()
32
33 tankWidth =
40
34 tankHeight =
20
35
36 turretWidth =
5
37 wheelWidth =
5
38
39 ground_height =
35
40
41 smallfont = pygame.font.SysFont(
"comicsansms", 25)
42 medfont = pygame.font.SysFont(
"comicsansms", 50)
43 largefont = pygame.font.SysFont(
"Times new Roman", 85)
44 vsmallfont = pygame.font.SysFont(
"Times new Roman", 25)
45
46 def score(score):
47     text = smallfont.render(
"Score: " + str(score), True, white)
48     gameDisplay.blit(text, [
0, 0])
49
50 def text_objects(text, color, size=
"small"):
51     
if size == "small":
52         textSurface = smallfont.render(text, True, color)
53     
if size == "medium":
54         textSurface = medfont.render(text, True, color)
55     
if size == "large":
56         textSurface = largefont.render(text, True, color)
57     
if size == "vsmall":
58         textSurface = vsmallfont.render(text, True, color)
59
60     
return textSurface, textSurface.get_rect()
61
62 def text_to_button(msg, color, buttonx, buttony, buttonwidth, buttonheight, size=
"vsmall"):
63     textSurf, textRect = text_objects(msg, color, size)
64     textRect.center = ((buttonx + (buttonwidth /
2)), buttony + (buttonheight / 2))
65     gameDisplay.blit(textSurf, textRect)
66
67 def message_to_screen(msg, color, y_displace=
0, size="small"):
68     textSurf, textRect = text_objects(msg, color, size)
69     textRect.center = (
int(display_width / 2), int(display_height / 2) + y_displace)
70     gameDisplay.blit(textSurf, textRect)
71
72 def tank(x, y, turPos):
73     x =
int(x)
74     y =
int(y)
75
76     possibleTurrets = [(x -
27, y - 2),
77                        (x -
26, y - 5),
78                        (x -
25, y - 8),
79                        (x -
23, y - 12),
80                        (x -
20, y - 14),
81                        (x -
18, y - 15),
82                        (x -
15, y - 17),
83                        (x -
13, y - 19),
84                        (x -
11, y - 21)
85                        ]
86
87     pygame.draw.circle(gameDisplay, pink, (x, y),
int(tankHeight / 2))
88     pygame.draw.rect(gameDisplay, pink, (x - tankHeight, y, tankWidth, tankHeight))
89
90     pygame.draw.line(gameDisplay, pink, (x, y), possibleTurrets[turPos], turretWidth)
91
92     pygame.draw.circle(gameDisplay, pink, (x -
15, y + 20), wheelWidth)
93     pygame.draw.circle(gameDisplay, pink, (x -
10, y + 20), wheelWidth)
94
95     pygame.draw.circle(gameDisplay, pink, (x -
15, y + 20), wheelWidth)
96     pygame.draw.circle(gameDisplay, pink, (x -
10, y + 20), wheelWidth)
97     pygame.draw.circle(gameDisplay, pink, (x -
5, y + 20), wheelWidth)
98     pygame.draw.circle(gameDisplay, pink, (x, y +
20), wheelWidth)
99     pygame.draw.circle(gameDisplay, pink, (x +
5, y + 20), wheelWidth)
100     pygame.draw.circle(gameDisplay, pink, (x +
10, y + 20), wheelWidth)
101     pygame.draw.circle(gameDisplay, pink, (x +
15, y + 20), wheelWidth)
102
103     
return possibleTurrets[turPos]
104
105 def enemy_tank(x, y, turPos):
106     x =
int(x)
107     y =
int(y)
108
109     possibleTurrets = [(x +
27, y - 2),
110                        (x +
26, y - 5),
111                        (x +
25, y - 8),
112                        (x +
23, y - 12),
113                        (x +
20, y - 14),
114                        (x +
18, y - 15),
115                        (x +
15, y - 17),
116                        (x +
13, y - 19),
117                        (x +
11, y - 21)
118                        ]
119
120     pygame.draw.circle(gameDisplay, blue, (x, y),
int(tankHeight / 2))
121     pygame.draw.rect(gameDisplay, blue, (x - tankHeight, y, tankWidth, tankHeight))
122
123     pygame.draw.line(gameDisplay, blue, (x, y), possibleTurrets[turPos], turretWidth)
124
125     pygame.draw.circle(gameDisplay, blue, (x -
15, y + 20), wheelWidth)
126     pygame.draw.circle(gameDisplay, blue, (x -
10, y + 20), wheelWidth)
127
128     pygame.draw.circle(gameDisplay, blue, (x -
15, y + 20), wheelWidth)
129     pygame.draw.circle(gameDisplay, blue, (x -
10, y + 20), wheelWidth)
130     pygame.draw.circle(gameDisplay, blue, (x -
5, y + 20), wheelWidth)
131     pygame.draw.circle(gameDisplay, blue, (x, y +
20), wheelWidth)
132     pygame.draw.circle(gameDisplay, blue, (x +
5, y + 20), wheelWidth)
133     pygame.draw.circle(gameDisplay, blue, (x +
10, y + 20), wheelWidth)
134     pygame.draw.circle(gameDisplay, blue, (x +
15, y + 20), wheelWidth)
135
136     
return possibleTurrets[turPos]
137
138 def game_controls():
139     gcont = True
140
141     
while gcont:
142         
for event in pygame.event.get():
143            
144             
if event.type == pygame.QUIT:
145                 pygame.quit()
146                 quit()
147
148         gameDisplay.fill(black)
149         message_to_screen(
"Controls", white, -100, size="large")
150         message_to_screen(
"Fire: Spacebar", wheat, -30)
151         message_to_screen(
"Move Turret: Up and Down arrows", wheat, 10)
152         message_to_screen(
"Move Tank: Left and Right arrows", wheat, 50)
153         message_to_screen(
"Press D to raise Power % AND Press A to lower Power % ", wheat, 140)
154         message_to_screen(
"Pause: P", wheat, 90)
155
156         button(
"Play", 150, 500, 100, 50, green, light_green, action="play")
157         button(
"Main", 350, 500, 100, 50, yellow, light_yellow, action="main")
158         button(
"Quit", 550, 500, 100, 50, red, light_red, action="quit")
159
160         pygame.display.update()
161
162         clock.tick(
15)
163
164 def button(text, x, y, width, height, inactive_color, active_color, action=None,size=
" "):
165     cur = pygame.mouse.get_pos()
166     click = pygame.mouse.get_pressed()
167     
168     
if x + width > cur[0] > x and y + height > cur[1] > y:
169         pygame.draw.rect(gameDisplay, active_color, (x, y, width, height))
170         
if click[0] == 1 and action != None:
171             
if action == "quit":
172                 pygame.quit()
173                 quit()
174
175             
if action == "controls":
176                 game_controls()
177
178             
if action == "play":
179                 gameLoop()
180
181             
if action == "main":
182                 game_intro()
183
184     
else:
185         pygame.draw.rect(gameDisplay, inactive_color, (x, y, width, height))
186
187     text_to_button(text, black, x, y, width, height)
188
189 def pause():
190     paused = True
191     message_to_screen(
"Paused", white, -100, size="large")
192     message_to_screen(
"Press C to continue playing or Q to quit", wheat, 25)
193     pygame.display.update()
194     
while paused:
195         
196         
for event in pygame.event.get():
197
198             
if event.type == pygame.QUIT:
199                 pygame.quit()
200                 quit()
201             
if event.type == pygame.KEYDOWN:
202                 
if event.key == pygame.K_c:
203                     paused = False
204                 elif
event.key == pygame.K_q:
205                     pygame.quit()
206                     quit()
207
208         clock.tick(
5)
209
210 def barrier(xlocation, randomHeight, barrier_width):
211     pygame.draw.rect(gameDisplay, green, [xlocation, display_height - randomHeight, barrier_width, randomHeight])
212
213 def explosion(x, y, size=
50):
214     
215     explode = True
216
217     
while explode:
218         
for event in pygame.event.get():
219             
if event.type == pygame.QUIT:
220                 pygame.quit()
221                 quit()
222
223         startPoint = x, y
224
225         colorChoices = [red, light_red, yellow, light_yellow]
226
227         magnitude =
1
228
229         
while magnitude < size:
230             exploding_bit_x = x + random.randrange(-
1 * magnitude, magnitude)
231             exploding_bit_y = y + random.randrange(-
1 * magnitude, magnitude)
232
233             pygame.draw.circle(gameDisplay, colorChoices[random.randrange(
0, 4)], (exploding_bit_x, exploding_bit_y),
234                                random.randrange(
1, 5))
235             magnitude +=
1
236
237             pygame.display.update()
238             clock.tick(
100)
239
240         explode = False
241
242 def fireShell(xy, tankx, tanky, turPos, gun_power, xlocation, barrier_width, randomHeight, enemyTankX, enemyTankY):
243     
244     fire = True
245     damage =
0
246
247     startingShell = list(xy)
248
249     print(
"FIRE!", xy)
250
251     
while fire:
252         
for event in pygame.event.get():
253             
if event.type == pygame.QUIT:
254                 pygame.quit()
255                 quit()
256
257         pygame.draw.circle(gameDisplay, red, (startingShell[
0], startingShell[1]), 5)
258
259         startingShell[
0] -= (12 - turPos) * 2
260
261        
262         startingShell[
1] += int(
263             (((startingShell[
0] - xy[0]) * 0.015 / (gun_power / 50)) ** 2) - (turPos + turPos / (12 - turPos)))
264
265         
if startingShell[1] > display_height - ground_height:
266             print(
"Last shell:", startingShell[0], startingShell[1])
267             hit_x =
int((startingShell[0] * display_height - ground_height) / startingShell[1])
268             hit_y =
int(display_height - ground_height)
269             print(
"Impact:", hit_x, hit_y)
270
271             
if enemyTankX + 10 > hit_x > enemyTankX - 10:
272                 print(
"Critical Hit!")
273                 damage =
25
274             elif enemyTankX +
15 > hit_x > enemyTankX - 15:
275                 print(
"Hard Hit!")
276                 damage =
18
277             elif enemyTankX +
25 > hit_x > enemyTankX - 25:
278                 print(
"Medium Hit")
279                 damage =
10
280             elif enemyTankX +
35 > hit_x > enemyTankX - 35:
281                 print(
"Light Hit")
282                 damage =
5
283
284             explosion(hit_x, hit_y)
285             fire = False
286
287         check_x_1 = startingShell[
0] <= xlocation + barrier_width
288         check_x_2 = startingShell[
0] >= xlocation
289
290         check_y_1 = startingShell[
1] <= display_height
291         check_y_2 = startingShell[
1] >= display_height - randomHeight
292
293         
if check_x_1 and check_x_2 and check_y_1 and check_y_2:
294             print(
"Last shell:", startingShell[0], startingShell[1])
295             hit_x =
int((startingShell[0]))
296             hit_y =
int(startingShell[1])
297             print(
"Impact:", hit_x, hit_y)
298             explosion(hit_x, hit_y)
299             fire = False
300
301         pygame.display.update()
302         clock.tick(
60)
303     
return damage
304
305 def e_fireShell(xy, tankx, tanky, turPos, gun_power, xlocation, barrier_width, randomHeight, ptankx, ptanky):
306     
307     damage =
0
308     currentPower =
1
309     power_found = False
310
311     
while not power_found:
312         currentPower +=
1
313         
if currentPower > 100:
314             power_found = True
315         # print(currentPower)
316
317         fire = True
318         startingShell = list(xy)
319
320         
while fire:
321             
for event in pygame.event.get():
322                 
if event.type == pygame.QUIT:
323                     pygame.quit()
324                     quit()
325
326             
327             startingShell[
0] += (12 - turPos) * 2
328             startingShell[
1] += int(
329                 (((startingShell[
0] - xy[0]) * 0.015 / (currentPower / 50)) ** 2) - (turPos + turPos / (12 - turPos)))
330
331             
if startingShell[1] > display_height - ground_height:
332                 hit_x =
int((startingShell[0] * display_height - ground_height) / startingShell[1])
333                 hit_y =
int(display_height - ground_height)
334                
335                 
if ptankx + 15 > hit_x > ptankx - 15:
336                     print(
"target acquired!")
337                     power_found = True
338                 fire = False
339
340             check_x_1 = startingShell[
0] <= xlocation + barrier_width
341             check_x_2 = startingShell[
0] >= xlocation
342
343             check_y_1 = startingShell[
1] <= display_height
344             check_y_2 = startingShell[
1] >= display_height - randomHeight
345
346             
if check_x_1 and check_x_2 and check_y_1 and check_y_2:
347                 hit_x =
int((startingShell[0]))
348                 hit_y =
int(startingShell[1])
349                 
350                 fire = False
351
352     fire = True
353     startingShell = list(xy)
354     print(
"FIRE!", xy)
355
356     
while fire:
357         
for event in pygame.event.get():
358             
if event.type == pygame.QUIT:
359                 pygame.quit()
360                 quit()
361        
362         pygame.draw.circle(gameDisplay, red, (startingShell[
0], startingShell[1]), 5)
363
364         startingShell[
0] += (12 - turPos) * 2
365
366        
367
368         gun_power = random.randrange(
int(currentPower * 0.90), int(currentPower * 1.10))
369
370         startingShell[
1] += int(
371             (((startingShell[
0] - xy[0]) * 0.015 / (gun_power / 50)) ** 2) - (turPos + turPos / (12 - turPos)))
372
373         
if startingShell[1] > display_height - ground_height:
374             print(
"last shell:", startingShell[0], startingShell[1])
375             hit_x =
int((startingShell[0] * display_height - ground_height) / startingShell[1])
376             hit_y =
int(display_height - ground_height)
377             print(
"Impact:", hit_x, hit_y)
378
379             
if ptankx + 10 > hit_x > ptankx - 10:
380                 print(
"Critical Hit!")
381                 damage =
25
382             elif ptankx +
15 > hit_x > ptankx - 15:
383                 print(
"Hard Hit!")
384                 damage =
18
385             elif ptankx +
25 > hit_x > ptankx - 25:
386                 print(
"Medium Hit")
387                 damage =
10
388             elif ptankx +
35 > hit_x > ptankx - 35:
389                 print(
"Light Hit")
390                 damage =
5
391
392             explosion(hit_x, hit_y)
393             fire = False
394
395         check_x_1 = startingShell[
0] <= xlocation + barrier_width
396         check_x_2 = startingShell[
0] >= xlocation
397
398         check_y_1 = startingShell[
1] <= display_height
399         check_y_2 = startingShell[
1] >= display_height - randomHeight
400
401         
if check_x_1 and check_x_2 and check_y_1 and check_y_2:
402             print(
"Last shell:", startingShell[0], startingShell[1])
403             hit_x =
int((startingShell[0]))
404             hit_y =
int(startingShell[1])
405             print(
"Impact:", hit_x, hit_y)
406             explosion(hit_x, hit_y)
407             fire = False
408
409         pygame.display.update()
410         clock.tick(
60)
411     
return damage
412
413 def power(level):
414     text = smallfont.render(
"Power: " + str(level) + "%", True, wheat)
415     gameDisplay.blit(text, [display_width /
2, 0])
416
417 def game_intro():
418     intro = True
419
420     
while intro:
421         
for event in pygame.event.get():
422             
if event.type == pygame.QUIT:
423                 pygame.quit()
424                 quit()
425
426             
if event.type == pygame.KEYDOWN:
427                 
if event.key == pygame.K_c:
428                     intro = False
429                 elif
event.key == pygame.K_q:
430
431                     pygame.quit()
432                     quit()
433
434         gameDisplay.fill(black)
435         message_to_screen(
"Tank Destroyer Game", white, -100, size="large")
436         message_to_screen(
"Shoot and dominate your enemy tank", wheat, 15)
437         message_to_screen(
"Bring glory for your homeland", wheat, 45)
438         button(
"Play", 150, 500, 100, 50, wheat, light_green, action="play",size="vsmall")
439         button(
"Controls", 350, 500, 100, 50, wheat, light_yellow, action="controls",size="vsmall")
440         button(
"Quit", 550, 500, 100, 50, wheat, light_red, action="quit",size="vsmall")
441
442         pygame.display.update()
443
444         clock.tick(
15)
445
446 def game_over():
447     game_over = True
448
449     
while game_over:
450         
for event in pygame.event.get():
451           
452             
if event.type == pygame.QUIT:
453                 pygame.quit()
454                 quit()
455
456         gameDisplay.fill(black)
457         message_to_screen(
"Game Over", white, -100, size="large")
458         message_to_screen(
"You died.", wheat, -30)
459
460         button(
"Play Again", 150, 500, 150, 50, wheat, light_green, action="play")
461         button(
"Controls", 350, 500, 100, 50, wheat, light_yellow, action="controls")
462         button(
"Quit", 550, 500, 100, 50, wheat, light_red, action="quit")
463
464         pygame.display.update()
465
466         clock.tick(
15)
467
468 def you_win():
469     win = True
470
471     
while win:
472         
for event in pygame.event.get():
473             
474             
if event.type == pygame.QUIT:
475                 pygame.quit()
476                 quit()
477
478         gameDisplay.fill(black)
479         message_to_screen(
"You won!", white, -100, size="large")
480         message_to_screen(
"Congratulations!", wheat, -30)
481
482         button(
"Play Again", 150, 500, 150, 50, wheat, light_green, action="play")
483         button(
"Controls", 350, 500, 100, 50, wheat, light_yellow, action="controls")
484         button(
"Quit", 550, 500, 100, 50, wheat, light_red, action="quit")
485
486         pygame.display.update()
487
488         clock.tick(
15)
489
490 def health_bars(player_health, enemy_health):
491     
if player_health > 75:
492         player_health_color = white
493     elif player_health >
50:
494         player_health_color = yellow
495     
else:
496         player_health_color = red
497
498     
if enemy_health > 75:
499         enemy_health_color = white
500     elif enemy_health >
50:
501         enemy_health_color = yellow
502     
else:
503         enemy_health_color = red
504
505     pygame.draw.rect(gameDisplay, player_health_color, (
680, 25, player_health, 25))
506     pygame.draw.rect(gameDisplay, enemy_health_color, (
20, 25, enemy_health, 25))
507
508 def gameLoop():
509     gameExit = False
510     gameOver = False
511     FPS =
15
512
513     player_health =
100
514     enemy_health =
100
515
516     barrier_width =
50
517
518     mainTankX = display_width *
0.9
519     mainTankY = display_height *
0.9
520     tankMove =
0
521     currentTurPos =
0
522     changeTur =
0
523
524     enemyTankX = display_width *
0.1
525     enemyTankY = display_height *
0.9
526
527     fire_power =
50
528     power_change =
0
529
530     xlocation = (display_width /
2) + random.randint(-0.1 * display_width, 0.1 * display_width)
531     randomHeight = random.randrange(display_height *
0.1, display_height * 0.6)
532
533     
while not gameExit:
534
535         
if gameOver == True:
536            
537             message_to_screen(
"Game Over", red, -50, size="large")
538             message_to_screen(
"Press C to play again or Q to exit", black, 50)
539             pygame.display.update()
540             
while gameOver == True:
541                 
for event in pygame.event.get():
542                     
if event.type == pygame.QUIT:
543                         gameExit = True
544                         gameOver = False
545
546                     
if event.type == pygame.KEYDOWN:
547                         
if event.key == pygame.K_c:
548                             gameLoop()
549                         elif
event.key == pygame.K_q:
550
551                             gameExit = True
552                             gameOver = False
553
554         
for event in pygame.event.get():
555
556             
if event.type == pygame.QUIT:
557                 gameExit = True
558
559             
if event.type == pygame.KEYDOWN:
560                 
if event.key == pygame.K_LEFT:
561                     tankMove = -
5
562
563                 elif
event.key == pygame.K_RIGHT:
564                     tankMove =
5
565
566                 elif
event.key == pygame.K_UP:
567                     changeTur =
1
568
569                 elif
event.key == pygame.K_DOWN:
570                     changeTur = -
1
571
572                 elif
event.key == pygame.K_p:
573                     pause()
574
575                 elif
event.key == pygame.K_SPACE:
576
577                     damage = fireShell(gun, mainTankX, mainTankY, currentTurPos, fire_power, xlocation, barrier_width,
578                                        randomHeight, enemyTankX, enemyTankY)
579                     enemy_health -= damage
580
581                     possibleMovement = [
'f', 'r']
582                     moveIndex = random.randrange(
0, 2)
583
584                     
for x in range(random.randrange(0, 10)):
585
586                         
if display_width * 0.3 > enemyTankX > display_width * 0.03:
587                             
if possibleMovement[moveIndex] == "f":
588                                 enemyTankX +=
5
589                             elif possibleMovement[moveIndex] ==
"r":
590                                 enemyTankX -=
5
591
592                             gameDisplay.fill(black)
593                             health_bars(player_health, enemy_health)
594                             gun = tank(mainTankX, mainTankY, currentTurPos)
595                             enemy_gun = enemy_tank(enemyTankX, enemyTankY,
8)
596                             fire_power += power_change
597
598                             power(fire_power)
599
600                             barrier(xlocation, randomHeight, barrier_width)
601                             gameDisplay.fill(green,
602                                              rect=[
0, display_height - ground_height, display_width, ground_height])
603                             pygame.display.update()
604
605                             clock.tick(FPS)
606
607                     damage = e_fireShell(enemy_gun, enemyTankX, enemyTankY,
8, 50, xlocation, barrier_width,
608                                          randomHeight, mainTankX, mainTankY)
609                     player_health -= damage
610
611                 elif
event.key == pygame.K_a:
612                     power_change = -
1
613                 elif
event.key == pygame.K_d:
614                     power_change =
1
615
616             elif
event.type == pygame.KEYUP:
617                 
if event.key == pygame.K_LEFT or event.key == pygame.K_RIGHT:
618                     tankMove =
0
619
620                 
if event.key == pygame.K_UP or event.key == pygame.K_DOWN:
621                     changeTur =
0
622
623                 
if event.key == pygame.K_a or event.key == pygame.K_d:
624                     power_change =
0
625
626         mainTankX += tankMove
627
628         currentTurPos += changeTur
629
630         
if currentTurPos > 8:
631             currentTurPos =
8
632         elif currentTurPos <
0:
633             currentTurPos =
0
634
635         
if mainTankX - (tankWidth / 2) < xlocation + barrier_width:
636             mainTankX +=
5
637
638         gameDisplay.fill(black)
639         health_bars(player_health, enemy_health)
640         gun = tank(mainTankX, mainTankY, currentTurPos)
641         enemy_gun = enemy_tank(enemyTankX, enemyTankY,
8)
642
643         fire_power += power_change
644
645         
if fire_power > 100:
646             fire_power =
100
647         elif fire_power <
1:
648             fire_power =
1
649
650         power(fire_power)
651
652         barrier(xlocation, randomHeight, barrier_width)
653         gameDisplay.fill(green, rect=[
0, display_height - ground_height, display_width, ground_height])
654         pygame.display.update()
655
656         
if player_health < 1:
657             game_over()
658         elif enemy_health <
1:
659             you_win()
660         clock.tick(FPS)
661
662     pygame.quit()
663     quit()
664
665 game_intro()
666 gameLoop()


Gõ tìm kiếm nhanh...